#include "StdAfx.h"
#include "CarAgent.h"
#include "Env.h"

CCarAgent::CCarAgent(int id, CNode* node, EAgentType type) 
    : CAgent(id, type, node)
{
}

CCarAgent::CCarAgent(int id, CPath* path) 
    : CAgent(id, ETYPE_CAR, path->GetSource())
{
    SetPath(path);
}

CCarAgent::~CCarAgent(void)
{
}

void CCarAgent::SetPath(CPath* path)
{    
    m_path = path;
    m_itPath = path->GetIterator();
}

bool CCarAgent::Step(CEnv* env, int ms)
{
    bool ret = __super::Step(env, ms);
    
    if (m_status != ESTATUS_TRANSIT)
    {
        m_action = CSysTime::Now();
        m_next = GetNextNode();

        if (m_next == NULL)
            return false;
        
        m_status = ESTATUS_TRANSIT;
    }
    else
    {    
        if (m_next == NULL)
            return false;

        if (m_pt == m_next->m_pt)
        {
            m_status = ESTATUS_STOPPED;
            m_node = m_next;
        }
    }

    UpdatePosition();

    return ret;
}

CNode* CCarAgent::GetNextNode()
{
    if (m_path && m_node != m_path->GetDestination())
        return *m_itPath++;
    else
        return NULL;
}

void CCarAgent::UpdatePosition()
{
    /* 
    This makes me puke...

    ...but its actually pretty easy. Get the number of seconds since the last action
    and multiply it by the PPS (pixels per second). That is how much the dot will
    move, in pixels. The rest of that mess is just to make sure its headed in the
    right directoin and to make sure it doesn't overshoot its target.
    */

    // Get the number of pixels dot should travel
    
    CSysTime diff = CSysTime::Now() - m_action;
    int pix = diff.GetSeconds() * PPS;

    // Get dx and dy, and with the right sign.
    int dx, dy;
    if (m_next->m_pt.x - m_node->m_pt.x > 0)
        dx = pix;
    else if (m_next->m_pt.x - m_node->m_pt.x < 0)
        dx = -1 * pix;
    else
        dx = 0;

    if (m_next->m_pt.y - m_node->m_pt.y > 0)
        dy = pix;
    else if (m_next->m_pt.y - m_node->m_pt.y < 0)
        dy = -1 * pix;
    else
        dy = 0;

    // Do the damn add already! We're moving from the previous node to the current node.
    m_pt.x = m_node->m_pt.x + dx;
    m_pt.y = m_node->m_pt.y + dy;

    // Correct overshoot
    if (dx > 0 && m_pt.x > m_next->m_pt.x)
        m_pt.x = m_next->m_pt.x;
    else if (dx < 0 && m_pt.x < m_next->m_pt.x)
        m_pt.x = m_next->m_pt.x;

    if (dy > 0 && m_pt.y > m_next->m_pt.y)
        m_pt.y = m_next->m_pt.y;
    else if (dy < 0 && m_pt.y < m_next->m_pt.y)
        m_pt.y = m_next->m_pt.y;
}

CNodePtrVec* CCarAgent::GetPathVector()
{
    if (m_path)
        return m_path->GetPath();
    else
        return NULL;
}